#include "CutSceneManager.h"
#include <daisy/OgreGraphicsManager.h>
using namespace  Branch1;
template<> CutSceneManager* Tools::Singleton<CutSceneManager>::_singleton = new CutSceneManager();
// class CutScene Def
CutScene::CutScene(const std::string& cutSceneName,int cutSceneIndex,float start,float end):
name(cutSceneName),
index(cutSceneIndex),
startTime(start),
endTime(end),
isFinish(false),
isLoad(false){}
CutScene::~CutScene(){}
bool CutScene::load(){return true;}
bool CutScene::unLoad(){return true;}

//class OgreCutSceen Def
OgreCutScene::OgreCutScene(const std::string& name,
	int cutSceneIndex,
	float start,
	float end,
	Ogre::Vector3 camPosit,
	Ogre::Quaternion camQuter, 
	Ogre::Vector3 playerPosit, 
	Ogre::Quaternion playerQuter,
	bool isAutoTracking,
	bool isUseCEGUI,
	std::string content,
	Ogre::Real rx,
	Ogre::Real ry):
	CutScene(name,cutSceneIndex,start,end),
	_camPosit(camPosit),
	_camQuter(camQuter),
	_playerPosit(playerPosit),
	_playerQuter(playerQuter),
	_isAutoTracking(isAutoTracking),
	_isUseCEGUI(isUseCEGUI),
	_CEGUIcontent(content),
	_rx(rx),
	_ry(ry),
	_wmgr(CEGUI::WindowManager::getSingletonPtr())
{
	_textPanel = _wmgr->getWindow("textPanel");
}

	
OgreCutScene::~OgreCutScene(){}
bool  OgreCutScene::init()
{
	_curCam = DAISY::OgreGraphicsManager::getInstance().getSceneManager()->getCamera("MainCamera");
	_playerBody =  DAISY::VariantData<OgreNewt::Body*>::get(Branch1::KnowledgeCenter::getInstance().getOffice("PlayerInfo")->getData("PlayerBody"));
	_playerNode = DAISY::VariantData<Ogre::SceneNode*>::get(Branch1::KnowledgeCenter::getInstance().getOffice("PlayerInfo")->getData("PlayerNode"));
	
	return true;
}
void OgreCutScene::destroy()
{
	_curCam = NULL;
	_playerBody = NULL;
	_playerNode  = NULL;
}

bool OgreCutScene::load()
{
	_curCam->setPosition(_camPosit);
	_curCam->setOrientation(_camQuter);
	_playerBody->setPositionOrientation(_playerPosit,_playerQuter);
	if(_isAutoTracking)
		_curCam->setAutoTracking(true,_playerNode);
	if(_isUseCEGUI)
	{
		_textPanel->setText(_CEGUIcontent);
		_textPanel->setPosition(CEGUI::UVector2(cegui_reldim(_rx),cegui_reldim(_ry)));
	}
	isLoad = true;
	return true;
}
bool OgreCutScene::unLoad()
{
	_curCam->setOrientation(Ogre::Quaternion::IDENTITY);
	_curCam->setPosition(Ogre::Vector3::ZERO);
	if(_isAutoTracking)
		_curCam->setAutoTracking(false);
	if(_isUseCEGUI)
	{
		_textPanel->setText("");
	}
	isFinish = true;
	return true;
}

//class CutSceneGroup Def
CutSceneGroup::CutSceneGroup():_timeLine(0.0f),_isPlaying(false){}
CutSceneGroup::~CutSceneGroup(){}
void CutSceneGroup::addTime(float interval)
{
	if(!_cutSceneList.empty())
	{
		if(_isPlaying)
		{
			_timeLine += interval;
			float startTemp = _timeLine - _cutSceneList.front()->startTime;
			float endTemp = _timeLine - _cutSceneList.front()->endTime;

			Branch1::CSPtr front = _cutSceneList.front();
			if(!front->isLoad&&(Ogre::Math::Abs(startTemp) < (interval/2)) )
			{
				
				_currCutScene = front;
				_currCutScene->load();

			}
			else if(!front->isLoad&&(front->startTime < _timeLine))
			{	

				_currCutScene = _cutSceneList.front();
				_currCutScene->load();

			}

			if(front->isLoad&&(Ogre::Math::Abs(endTemp) < (interval/2)))
			{
				front->unLoad();
				_cutSceneList.pop_front();
				if(!_cutSceneList.empty())
					_cutSceneList.front()->load();

			}else if(front->isLoad&&front->endTime < _timeLine)
			{
				front->unLoad();
				_cutSceneList.pop_front();
				if(!_cutSceneList.empty())
					_cutSceneList.front()->load();
			}
			
		}
	}else
	{
		_isPlaying = false;
	}
}
void CutSceneGroup::play()
{
	_isPlaying = true;
}
void CutSceneGroup::stop()
{
	if(_isPlaying)
		_isPlaying = false;
}
void CutSceneGroup::play(int index)
{
	//TODO
}
void CutSceneGroup::showNext()
{
	if(!_cutSceneList.empty())
	{
		if(_currCutScene.get())
			_currCutScene->unLoad();

		_currCutScene = _cutSceneList.front();
		_currCutScene->load();

		_cutSceneList.pop_front();
	}
	
}
bool CutSceneGroup::isPlaying()
{
	return _isPlaying;
}
void CutSceneGroup::addCutScene(CutScene* cutScene)
{
	CSPtr newCutScene;
	newCutScene.reset(cutScene);
	_cutSceneList.push_back(newCutScene);
}
void CutSceneGroup::reset()
{
	_timeLine = 0.0f;
}

//class CutSceneManager Def
bool CutSceneManager::init()
{return true;}
void CutSceneManager::shutDown()
{}
void CutSceneManager::addTime(float interval)
{
	std::map<const std::string,CSGPtr>::const_iterator it;
	for(it = _cutSceneGroupMap.begin(); it != _cutSceneGroupMap.end();it++)
	{
		it->second->addTime(interval);
	}
}
void CutSceneManager::play(const std::string& cutsceneGroupName)
{
	_cutSceneGroupMap[cutsceneGroupName]->play();
}
void CutSceneManager::stop(const std::string& cutsceneGroupName)
{
	_cutSceneGroupMap[cutsceneGroupName]->stop();
}
void CutSceneManager::nextCutScene(const std::string& cutsceneGroupName)
{
	_cutSceneGroupMap[cutsceneGroupName]->showNext();
}
bool CutSceneManager::isPlaying(const std::string& cutsceneGroupName)
{
	return _cutSceneGroupMap[cutsceneGroupName]->isPlaying();
}
void CutSceneManager::addCutSceneGroup(const std::string& key,CutSceneGroup* csg)
{
	_cutSceneGroupMap[key].reset(csg);
}
void CutSceneManager::reset(const std::string& key)
{
	_cutSceneGroupMap[key]->reset();
}
Ogre::Camera* OgreCutScene::_curCam = NULL;
OgreNewt::Body* OgreCutScene::_playerBody = NULL;
Ogre::SceneNode* OgreCutScene::_playerNode = NULL;
